# -*- coding:utf-8 -*-
import json
import os
import re
import time
import urllib
import pymysql
import requests
from .celery import app
from apps.interface.models import SuitCase
# from set.models import Set
# from bug.models import Bug as bug
from django.utils.html import format_html


def PATH(p):
    return os.path.abspath(os.path.join(os.path.dirname(__file__), p))


global driver


@app.task
def hello_world():
    print('已运行')


@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))


@app.task
def apisauto_testcase(suitID):
    """
    @description: 单接口测试用例的入口，目前没有添加执行条件，会把所有的单接口测试用例依次执行
    @param {type}
    @return: 无返回值
    """
    # 获取所有测试用例，后期可以加上是否有效的条件
    info = list(SuitCase.objects.filter(suite=suitID).values())
    interfaceTest1(info)
    pass


def interfaceTest1(case_list):
    """
    @description: 单接口测试用例执行
    @case_list {type：list} ：测试用例列表，列表元素为字典，
        如：[{"":"","":"","":""},
            {"":"","":"","":""},
            {"":"","":"","":""}]
    @return: 返回执行结果，type：dict。如：{"":"","":"","":""}
    """
    # res_flags = []
    request_urls = []
    # responses = []
    # strinfo = re.compile('{HOSTNAME}')
    for case in case_list:
        try:
            case_id = case['id']
            case_name = case['case_id']
            case_interface_name = case['interface_id']
            case_headers = case['interface_header']
            case_host = case['interface_host_name']
            case_method = case['interface_method']
            case_protocol = case['interface_protocol']
            case_url = case['interface_url']
            case_data = case['case_data']
            case_res_check = case['case_expected']
        except Exception as e:
            return {'code': 'Fail', 'msg': '测试用例格式不正确！%s'} % e
        if case_data == '':
            new_url = case_protocol + '://' + case_host + case_url
        elif case_data == 'null':
            new_url = case_protocol + '://' + case_host + case_url
        else:
            new_url = case_protocol + '://' + case_host + case_url
            request_urls.append(new_url)

        if case_method.upper() == "POST":
            print("我在执行POST方法！！！！！！！！！！！！！")
            # headers = {'Authorization': '', 'Content-Type': 'application/json'}
            headers = case_headers
            if "=" in urlParam(case_data):
                data = None
                try:
                    # 调用接口，并记录测试结果，获取的结果为json格式，需转换为str
                    # 采用url方式调用
                    results = str(requests.post(new_url + '?' + urlParam(case_data),
                                                data,
                                                headers=headers).json())
                except Exception as e:
                    print("我出错了！！！")
                    return caseWriteResult1(case_id, str(e), '0')
            else:
                print(' request  is POST2 ' + new_url + '   body is ' +
                      urlParam(case_data))
                data = case_data
                try:
                    results = str(requests.post(new_url, data, headers).json())
                except Exception as e:
                    print("我出错了！！！")
                    return caseWriteResult1(case_id, str(e), '0')
        if case_method.upper() == 'GET':
            # headers = {'Authorization': '', 'Content-Type': 'application/json'}
            headers = case_headers
            if "=" in urlParam(case_data):
                data = None
                print(
                    str(case_id) + ' request  is get' +
                    new_url + '?' +
                    urlParam(case_data))

                results = str(requests.get(new_url + '?' + urlParam(case_data),
                                       data,
                                       headers=headers).json)
                print('   response is get' + results)
            else:
                print(' request  is get ' + new_url + '   body is ' +
                      urlParam(case_data))
                data = None
                try:
                    results = str(requests.get(new_url, params=data, headers=headers).json())
                    print('   response is get1 ')
                    print(results)
                except Exception as e:
                    return caseWriteResult1(case_id, str(e), '0')

        if case_method.upper() == 'PUT':
            headers = {
                'Host': case_host,
                'Connection': 'keep-alive',
                'CredentialId': id,
                'Content-Type': 'application/json'
            }
            body_data = case_data
            results = str(requests.put(url=case_url, data=body_data, headers=headers).json())

        if case_method.upper() == "PATCH":
            headers = {
                'Authorization': 'Credential ' + id,
                'Content-Type': 'application/json'
            }
            data = None
            results = str(requests.patch(new_url + '?' + urlParam(case_data),
                                         data,
                                         headers=headers).json)

        res = readRes(results, case_res_check)
        # res = json.loads(res)
        # print('res_ytpe:',res['code'])
        if 'pass' == res['code']:
            caseWriteResult1(case_id, results, '1')
        else:
            caseWriteResult1(case_id, results, '0')
            print("发现bug，开始写bug：", case_interface_name)
            writeBug(case_id, "product", case_interface_name, new_url,
                     results, case_res_check)
    return res


def readRes(result, res_check):
    """
        进行字符串比对，判断测试结果和预期是否一致
        比对是按照字符串查找方式进行不对，找到指定的字符串即为通过
        res:字符串格式，非字典格式

    """
    # print("res:", res)
    # print("res_check:", res_check)
    result = result.replace('":"', "=").replace('":', "=")
    res_check = res_check.split(';')
    for s in res_check:
        if s in result:
            resultPass = {"code": "pass", "msg": "测试通过！"}
            return resultPass
        else:
            result="{"+str(result)+"}"
            # res_check="{"+str(res_check)+"}"
            print("====++++====:",result)
            msg = format_html(
                "<td>错误，返回参数和预期结果不一致</td><br/>\
                <td>预期结果为：'{}'</td><br/>\
                <td>实际结果为：'{}'</td><br/>"                                                                                                                                                                                                                                                                                               .format(res_check, res))
            print("我一定要找到你：",msg)
            resultFail = {'code': 'Fail', 'msg': msg}
            return resultFail


def urlParam(param):
    param1 = param.replace('&quot;', '"')
    return param1


def CredentialId():
    global id
    url = 'http://' + 'api.test.com.cn' +\
        '/api/Security/Authentication/Signin/web'
    body_data = json.dumps({"Identity": 'test', "Password": 'test'})
    headers = {'Connection': 'keep-alive', 'Content-Type': 'application/json'}
    response = requests.post(url=url, data=body_data, headers=headers)
    data = response.text
    regx = '.*"CredentialId":"(.*)","Scene"'
    pm = re.search(regx, data)
    id = pm.group(1)


def caseWriteResult1(case_id, response, result):
    """
    更新用例的执行状态，并记录实际返回结果
    case_id：传入测试用例的id，int类型
    response：请求的内容，str类型
    result：请求的内容，str类型
    """
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    Apis.objects.filter(id=case_id).update(
        apiresponse=response, apistatus=result, create_time=now)


def writeBug(bug_id, product_id, interface_name, request, response, res_check):
    """
    记录测试bug
    bug_id：传入测试用例的id，int类型
    product_id：用例关联产品的id，int类型
    interface_name：用例接口的名称，str类型
    request：请求的内容，str类型
    response：请求的内容，str类型
    res_check：请求的内容，str类型
    """
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    print("BUG_id type:", type(bug_id))
    print("interface_name:", interface_name)
    bugname = str(bug_id) + '_' + interface_name + '_出错了'
    bugdetail = '[请求数据]<br />' + request +\
        '<br/>' + '[预期结果]<br/>' + res_check +\
        '<br/>' + '<br/>' + '[响应数据]<br />' + '<br/>' + response

    bug.objects.create(bugname=bugname,
                       Product_id=product_id,
                       bugdetail=bugdetail,
                       bugstatus='激活',
                       buglevel='3',
                       bugcreater='seawave',
                       bugassign='seawave',
                       created_time=now)
    print("BUG已经生成！！！")


@app.task
def apitest_testcase():
    sql = "SELECT id,`apiname`,apiurl,apimethod,\
    apiparamvalue,apiresult,`apistatus` \
    from apitest_apistep where apitest_apistep.Apitest_id=2 "

    coon = pymysql.connect(user='root',
                           passwd='A2T4PrrJ3yM',
                           db='autotestplat',
                           port=3306,
                           host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    aa = cursor.execute(sql)
    info = cursor.fetchmany(aa)
    print(info)
    for ii in info:
        case_list = []
        case_list.append(ii)
        #   CredentialId()
        interfaceTest(case_list)
    coon.commit()
    cursor.close()
    coon.close()


def interfaceTest(case_list):
    res_flags = []
    request_urls = []
    responses = []
    strinfo = re.compile('{seturl}')
    tasknoinfo = re.compile('{taskno}')

    for case in case_list:

        try:
            case_id = case.id
            interface_name = case.apiname
            method = case.apimethod
            url = case.apiurl
            param = case.apiparamvalue
            res_check = case.apiresult
        except Exception as e:
            return '测试用例格式不正确！%s' % e
        if param == '':
            new_url = 'http://' + 'api.test.com.cn' + url
        elif param == 'null':
            url = strinfo.sub(str(seturl('HOSTNAME')), url)
            new_url = 'http://' + url
        else:
            url = strinfo.sub(str(seturl('HOSTNAME')), url)
            param = strinfo.sub(TaskId, param)
            param = tasknoinfo.sub(taskno, param)
            new_url = 'http://' + url
            request_urls.append(new_url)
        if method.upper() == 'GET':
            headers = {'Authorization': '', 'Content-Type': 'application/json'}
            if "=" in urlParam(param):
                data = None
                print(
                    str(case_id) + ' request  is get' +
                    new_url.encode('utf-8') + '?' +
                    urlParam(param).encode('utf-8'))
                results = requests.get(new_url + '?' + urlParam(param),
                                       data,
                                       headers=headers).text
                print('   response is get' + results.encode('utf-8'))
                responses.append(results)
                res = readRes(results, '')
            else:
                print(' request  is get ' + new_url + '   body is ' +
                      urlParam(param))
                data = None
                req = urllib.request.Request(url=new_url,
                                             data=data,
                                             headers=headers,
                                             method="GET")
                results = urllib.request.urlopen(req).read()
                print('   response is get ')
                print(results)
                res = readRes(results, res_check)
                if 'pass' == res:
                    res_flags.append('pass')
                    writeResult(case_id, results, '1')
                    caseWriteResult(case_id, '1')
                else:
                    res_flags.append('fail')
                    writeResult(case_id, results, '0')
                    caseWriteResult(case_id, '0')
                    writeBug(case_id, product_id, interface_name, new_url,
                             results, res_check)
        if method.upper() == 'PUT':
            headers = {
                'Host': HOSTNAME,
                'Connection': 'keep-alive',
                'CredentialId': id,
                'Content-Type': 'application/json'
            }
            body_data = param
            results = requests.put(url=url, data=body_data, headers=headers)
            responses.append(results)
            res = readRes(results, res_check)
            if 'pass' == res:
                writeResult(case_id, '', 'pass')
                res_flags.append('pass')
            else:
                res_flags.append('fail')
                writeResult(case_id, '', 'fail')
                writeBug(case_id, product_id, interface_name, new_url, results,
                         res_check)
            try:
                preOrderSN(results)
            except:
                print('ok')
        if method.upper() == "PATCH":
            headers = {
                'Authorization': 'Credential ' + id,
                'Content-Type': 'application/json'
            }
            data = None
            results = requests.patch(new_url + '?' + urlParam(param),
                                     data,
                                     headers=headers).text
            responses.append(results)
            res = readRes(results, res_check)
            if 'pass' == res:
                writeResult(case_id, '', 'pass')
                res_flags.append('pass')
            else:
                res_flags.append('fail')
                writeResult(case_id, '', 'fail')
                writeBug(case_id, product_id, interface_name, new_url, results,
                         res_check)
            try:
                preOrderSN(results)
            except:
                print('ok')
        if method.upper() == "POST":
            headers = {'Authorization': '', 'Content-Type': 'application/json'}
            if "=" in urlParam(param):
                data = None
                print(
                    str(case_id) + ' request  is POST' +
                    new_url.encode('utf-8') + '?' +
                    urlParam(param).encode('utf-8'))
                results = requests.post(new_url + '?' + urlParam(param),
                                        data,
                                        headers=headers).text
                print('   response is POST' + results.encode('utf-8'))
                responses.append(results)
                res = readRes(results, '')
            else:
                print('request  is POST ' + new_url + '   body is ' +
                      urlParam(param))

                data = None
                req = urllib.request.Request(url=new_url,
                                             data=data,
                                             headers=headers,
                                             method="POST")
                try:
                    results = urllib.request.urlopen(req).read()
                    print('   response is POST ')
                    print(results)
                except Exception as e:
                    return caseWriteResult1(case_id, results, '0')
                res = readRes(results, res_check)
                print(res)
                if 'pass' == res:
                    res_flags.append('pass')
                    caseWriteResult1(case_id, results, '1')
                else:
                    res_flags.append('fail')
                    caseWriteResult1(case_id, results, '0')
                    writeBug(case_id, product_id, interface_name, new_url,
                             results, res_check)
            try:
                TaskId(results)
            except:
                print('ok1')


def seturl(set):
    '''
    描述：生成全局变量
    @set:string,全局变量配置
    '''
    global setvalue
    setvalue = '127.0.0.1'
    print('setvalue:', setvalue)
    info = list(Set.objects.filter(setname = set).values())
    print("info:", info)
    if len(info) == 1:
        setvalue = info[0]['setvalue']
    print("return  setvalue:", setvalue)
    return setvalue


def preOrderSN(results):
    global preOrderSN
    regx = '.*"preOrderSN":"(.*)","toHome"'
    pm = re.search(regx, results)
    if pm:
        preOrderSN = pm.group(1).encode('utf-8')
        return preOrderSN
    return False


def TaskId(results):
    global TaskId
    regx = '.*"TaskId":(.*),"PlanId"'
    pm = re.search(regx, results)
    if pm:
        TaskId = pm.group(1).encode('utf-8')
        #  print TaskId
        return TaskId
    return False


def taskno(param):
    global taskno
    a = int(time.time())
    taskno = 'task_' + str(a)
    return taskno


def writeResult(case_id, response, result):
    result = result.encode('utf-8')
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    sql = "UPDATE apitest_apistep set apitest_apistep.apiresponse=%s,\
    apitest_apistep.apistatus=%s,\
    apitest_apistep.create_time=%s where apitest_apistep.id=%s;"

    param = (response, result, now, case_id)
    print('api autotest result is ' + result.decode())
    coon = pymysql.connect(user='root',
                           passwd='test123456',
                           db='autotest',
                           port=3306,
                           host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    cursor.execute(sql, param)
    coon.commit()
    cursor.close()
    coon.close()


def caseWriteResult(case_id, result):
    result = result.encode('utf-8')
    now = time.strftime("%Y-%m-%d %H:%M:%S")
    sql = "UPDATE apitest_apitest set apitest_apitest.apitestresult=%s,\
    apitest_apitest.create_time=%s where apitest_apitest.id=%s;"

    param = (result, now, case_id)
    print('api autotest result is ' + result.decode())
    coon = pymysql.connect(user='root',
                           passwd='test123456',
                           db='autotest',
                           port=3306,
                           host='127.0.0.1',
                           charset='utf8')
    cursor = coon.cursor()
    cursor.execute(sql, param)
    coon.commit()
    cursor.close()
    coon.close()
